package common.web;

import common.DatabaseConstants;
import common.model.GenericEntityBean;
import common.util.FacesUtil;
import java.io.Serializable;
import java.util.Date;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.transaction.UserTransaction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
 * @author shousuke
 */
public abstract class GenericController implements Serializable {

    protected final Log log = LogFactory.getLog(getClass());
    @Resource
    protected UserTransaction utx = null;

    public abstract EntityManager getEntityManager();

    public abstract boolean isSessionController();

    public GenericController findEntityBean(Long id) {
        return getEntityManager().find(getClass(), id);
    }

    public <T extends GenericEntityBean> boolean persist(T entityBean, String entityBeanName, boolean showSuccessMessage) {
        boolean status = false;
        EntityManager em = getEntityManager();
        try {
            utx.begin();
            Date date = new Date();
            entityBean.setCreatedDate(date);
            entityBean.setModifiedDate(date);
            entityBean.setOprtnlFlag(DatabaseConstants.OPRTNL_FLG_ACTIVE);
            log.info("Persisting the following entity bean: " + entityBean);
            em.persist(entityBean);
            utx.commit();
            if (showSuccessMessage) {
                FacesUtil.addSuccessMessage(entityBeanName + " was successfully created.");
            }
            status = true;
        } catch (Exception ex) {
            try {
                FacesUtil.addExceptionMessage(ex, "A persistence error occurred.");
                utx.rollback();
            } catch (Exception e) {
                FacesUtil.addExceptionMessage(e, "An error occurred attempting to roll back the transaction.");
            }
        } finally {
            if (isSessionController()) {
                em.close();
            }
        }
        return status;
    }

    public <T extends GenericEntityBean> boolean persist(T entityBean, String entityBeanName) {
        return persist(entityBean, entityBeanName, true);
    }

    public <T extends GenericEntityBean> boolean persist(T entityBean) {
        return persist(entityBean, null, false);
    }

    public <T extends GenericEntityBean> boolean merge(T entityBean, String entityBeanName, boolean showSuccessMessage) {
        boolean status = false;
        EntityManager em = getEntityManager();
        try {
            utx.begin();
            entityBean.setModifiedDate(new Date());
            log.info("Merging the following entity bean: " + entityBean);
            em.merge(entityBean);
            utx.commit();
            if (showSuccessMessage) {
                FacesUtil.addSuccessMessage(entityBeanName + " was successfully updated.");
            }
            status = true;
        } catch (Exception ex) {
            try {
                FacesUtil.addExceptionMessage(ex, "A persistence error occurred.");
                utx.rollback();
            } catch (Exception e) {
                FacesUtil.addExceptionMessage(e, "An error occurred attempting to roll back the transaction.");
            }
        } finally {
            if (em.isOpen()) {
                em.close();
            }
        }
        return status;
    }

    public <T extends GenericEntityBean> boolean merge(T entityBean) {
        return merge(entityBean, null, false);
    }

    public <T extends GenericEntityBean> boolean merge(T entityBean, String entityBeanName) {
        return merge(entityBean, entityBeanName, true);
    }
}
